/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * Main.java
 *
 * Created on 16/07/2011, 16:42:54
 */
package front_end;

import csm.uttils.Archive;
import csm.uttils.generics.Roster;
import front_end.tree.CustomIconRenderer;
import java.io.File;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.MutableTreeNode;
import javax.swing.tree.TreePath;
import tsb.xmlparser.Node;
import tsb.xmlparser.XmlParser;
import tsb.xmlparser.exceptions.OnParsingException;

/**
 *
 * @author Carlos S. Moreno <CarlosS.Moreno@gmail.com>
 */
public class Main extends javax.swing.JFrame {

    Archive openFile = null;
    TreePath onEditPath = null;
    boolean loading = false;
    boolean changed = false;

    /** Creates new form Main */
    public Main() {

        this.setIconImage(new ImageIcon(getClass().getResource("/icon/JParser.png")).getImage());

        splashScreen();
        initComponents();
        postSettings();
    }

    private void editNode() {

        onEditPath = jTree.getSelectionPath();
        Node nodeObj = (Node) (((DefaultMutableTreeNode) onEditPath.getLastPathComponent()).getUserObject());
        loadEdit(nodeObj);
        jspRight.setVisible(true);
        jspPane.setDividerLocation(jspPane.getWidth() - 240);
    }

    private void postSettings() {
        jTree.setCellRenderer(new CustomIconRenderer());
        jspPane.setResizeWeight(1.0);
        jspRight.setVisible(false);
    }

    private void splashScreen() {
        new Thread() {

            public void run() {
                try {
                    Splash sp = new Splash();
                    sp.setVisible(true);
                    Thread.sleep(1500);
                    sp.dispose();
                } catch (InterruptedException ex) {
                    Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        }.start();
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        treePopupMenu = new javax.swing.JPopupMenu();
        pmnuAdd = new javax.swing.JMenuItem();
        pmnuRemove = new javax.swing.JMenuItem();
        jSeparator3 = new javax.swing.JPopupMenu.Separator();
        pmnuEdit = new javax.swing.JMenuItem();
        hToolBar = new javax.swing.JToolBar();
        btnNew = new javax.swing.JButton();
        btnOpen = new javax.swing.JButton();
        jSeparator1 = new javax.swing.JToolBar.Separator();
        btnSave = new javax.swing.JButton();
        jSeparator2 = new javax.swing.JToolBar.Separator();
        btnAbout = new javax.swing.JButton();
        vToolBar = new javax.swing.JToolBar();
        btnAdd = new javax.swing.JButton();
        btnRemove = new javax.swing.JButton();
        btnEdit = new javax.swing.JButton();
        jspPane = new javax.swing.JSplitPane();
        jScrollPane1 = new javax.swing.JScrollPane();
        jTree = new javax.swing.JTree();
        jspRight = new javax.swing.JPanel();
        jLabel1 = new javax.swing.JLabel();
        jLabel2 = new javax.swing.JLabel();
        txtName = new javax.swing.JTextField();
        jScrollPane2 = new javax.swing.JScrollPane();
        jTable = new javax.swing.JTable();
        btnSaveNode = new javax.swing.JButton();
        btnRevert = new javax.swing.JButton();
        jtbPin = new javax.swing.JToggleButton();
        txtValue = new javax.swing.JTextField();
        btnNewAtt = new javax.swing.JButton();
        btnRemAtt = new javax.swing.JButton();
        jSeparator4 = new javax.swing.JSeparator();
        jPanel1 = new javax.swing.JPanel();
        lblLastAction = new javax.swing.JLabel();

        pmnuAdd.setIcon(new javax.swing.ImageIcon(getClass().getResource("/images/add.png"))); // NOI18N
        pmnuAdd.setMnemonic('a');
        pmnuAdd.setText("Add Node");
        pmnuAdd.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                pmnuAddActionPerformed(evt);
            }
        });
        treePopupMenu.add(pmnuAdd);

        pmnuRemove.setIcon(new javax.swing.ImageIcon(getClass().getResource("/images/delete.png"))); // NOI18N
        pmnuRemove.setMnemonic('r');
        pmnuRemove.setText("Remove Node");
        pmnuRemove.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                pmnuRemoveActionPerformed(evt);
            }
        });
        treePopupMenu.add(pmnuRemove);
        treePopupMenu.add(jSeparator3);

        pmnuEdit.setIcon(new javax.swing.ImageIcon(getClass().getResource("/images/pencil.png"))); // NOI18N
        pmnuEdit.setMnemonic('e');
        pmnuEdit.setText("Edit Node");
        pmnuEdit.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                pmnuEditActionPerformed(evt);
            }
        });
        treePopupMenu.add(pmnuEdit);

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("XML JParser");
        setName("main"); // NOI18N

        hToolBar.setFloatable(false);
        hToolBar.setRollover(true);

        btnNew.setIcon(new javax.swing.ImageIcon(getClass().getResource("/images/xhtml_add.png"))); // NOI18N
        btnNew.setMnemonic('n');
        btnNew.setToolTipText("New XML Document");
        btnNew.setFocusable(false);
        btnNew.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        btnNew.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        btnNew.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnNewActionPerformed(evt);
            }
        });
        hToolBar.add(btnNew);

        btnOpen.setIcon(new javax.swing.ImageIcon(getClass().getResource("/images/folder.png"))); // NOI18N
        btnOpen.setMnemonic('o');
        btnOpen.setToolTipText("Open an XML Document");
        btnOpen.setFocusable(false);
        btnOpen.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        btnOpen.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        btnOpen.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnOpenActionPerformed(evt);
            }
        });
        hToolBar.add(btnOpen);
        hToolBar.add(jSeparator1);

        btnSave.setIcon(new javax.swing.ImageIcon(getClass().getResource("/images/disk_multiple.png"))); // NOI18N
        btnSave.setMnemonic('s');
        btnSave.setToolTipText("Save the current XML Document");
        btnSave.setEnabled(false);
        btnSave.setFocusable(false);
        btnSave.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        btnSave.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        btnSave.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnSaveActionPerformed(evt);
            }
        });
        hToolBar.add(btnSave);
        hToolBar.add(jSeparator2);

        btnAbout.setIcon(new javax.swing.ImageIcon(getClass().getResource("/images/help.png"))); // NOI18N
        btnAbout.setMnemonic('h');
        btnAbout.setToolTipText("Help");
        btnAbout.setFocusable(false);
        btnAbout.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        btnAbout.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        btnAbout.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnAboutActionPerformed(evt);
            }
        });
        hToolBar.add(btnAbout);

        vToolBar.setFloatable(false);
        vToolBar.setOrientation(1);
        vToolBar.setRollover(true);

        btnAdd.setIcon(new javax.swing.ImageIcon(getClass().getResource("/images/add.png"))); // NOI18N
        btnAdd.setMnemonic('a');
        btnAdd.setToolTipText("Add a Node");
        btnAdd.setEnabled(false);
        btnAdd.setFocusable(false);
        btnAdd.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        btnAdd.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        btnAdd.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnAddActionPerformed(evt);
            }
        });
        vToolBar.add(btnAdd);

        btnRemove.setIcon(new javax.swing.ImageIcon(getClass().getResource("/images/delete.png"))); // NOI18N
        btnRemove.setMnemonic('r');
        btnRemove.setToolTipText("Remove a Node");
        btnRemove.setEnabled(false);
        btnRemove.setFocusable(false);
        btnRemove.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        btnRemove.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        btnRemove.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnRemoveActionPerformed(evt);
            }
        });
        vToolBar.add(btnRemove);

        btnEdit.setIcon(new javax.swing.ImageIcon(getClass().getResource("/images/pencil.png"))); // NOI18N
        btnEdit.setMnemonic('e');
        btnEdit.setToolTipText("Edit");
        btnEdit.setEnabled(false);
        btnEdit.setFocusable(false);
        btnEdit.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        btnEdit.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        btnEdit.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnEditActionPerformed(evt);
            }
        });
        vToolBar.add(btnEdit);

        jspPane.setDividerLocation(170);
        jspPane.setDividerSize(1);
        jspPane.setEnabled(false);

        jTree.setModel(new DefaultTreeModel(new DefaultMutableTreeNode(new Node("", null))));
        jTree.setDoubleBuffered(true);
        jTree.setDragEnabled(true);
        jTree.setEnabled(false);
        jTree.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                jTreeMouseClicked(evt);
            }
        });
        jTree.addTreeSelectionListener(new javax.swing.event.TreeSelectionListener() {
            public void valueChanged(javax.swing.event.TreeSelectionEvent evt) {
                jTreeValueChanged(evt);
            }
        });
        jScrollPane1.setViewportView(jTree);

        jspPane.setLeftComponent(jScrollPane1);

        jLabel1.setText("Name");

        jLabel2.setText("Value");

        txtName.setMinimumSize(new java.awt.Dimension(0, 28));

        jTable.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {

            },
            new String [] {
                "Title 1", "Title 2"
            }
        ) {
            Class[] types = new Class [] {
                java.lang.String.class, java.lang.String.class
            };

            public Class getColumnClass(int columnIndex) {
                return types [columnIndex];
            }
        });
        jScrollPane2.setViewportView(jTable);

        btnSaveNode.setIcon(new javax.swing.ImageIcon(getClass().getResource("/images/disk.png"))); // NOI18N
        btnSaveNode.setMnemonic('s');
        btnSaveNode.setToolTipText("Save Node");
        btnSaveNode.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnSaveNodeActionPerformed(evt);
            }
        });

        btnRevert.setIcon(new javax.swing.ImageIcon(getClass().getResource("/images/cancel.png"))); // NOI18N
        btnRevert.setMnemonic('c');
        btnRevert.setToolTipText("Cancel Edit");
        btnRevert.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnRevertActionPerformed(evt);
            }
        });

        jtbPin.setBackground(new java.awt.Color(237, 236, 235));
        jtbPin.setIcon(new javax.swing.ImageIcon(getClass().getResource("/images/pin-icon.png"))); // NOI18N
        jtbPin.setToolTipText("Attach Edit Panel");
        jtbPin.setBorderPainted(false);
        jtbPin.setSelectedIcon(new javax.swing.ImageIcon(getClass().getResource("/images/node.png"))); // NOI18N

        txtValue.setMinimumSize(new java.awt.Dimension(0, 28));
        txtValue.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                txtValueActionPerformed(evt);
            }
        });
        txtValue.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyReleased(java.awt.event.KeyEvent evt) {
                txtValueKeyReleased(evt);
            }
        });

        btnNewAtt.setIcon(new javax.swing.ImageIcon(getClass().getResource("/images/add.png"))); // NOI18N
        btnNewAtt.setToolTipText("New Attribute");
        btnNewAtt.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnNewAttActionPerformed(evt);
            }
        });

        btnRemAtt.setIcon(new javax.swing.ImageIcon(getClass().getResource("/images/delete.png"))); // NOI18N
        btnRemAtt.setToolTipText("Remove Attribute");
        btnRemAtt.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnRemAttActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout jspRightLayout = new javax.swing.GroupLayout(jspRight);
        jspRight.setLayout(jspRightLayout);
        jspRightLayout.setHorizontalGroup(
            jspRightLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jspRightLayout.createSequentialGroup()
                .addGroup(jspRightLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addGroup(javax.swing.GroupLayout.Alignment.LEADING, jspRightLayout.createSequentialGroup()
                        .addContainerGap()
                        .addGroup(jspRightLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(txtValue, javax.swing.GroupLayout.DEFAULT_SIZE, 342, Short.MAX_VALUE)
                            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jspRightLayout.createSequentialGroup()
                                .addComponent(btnSaveNode)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addComponent(btnRevert))
                            .addComponent(jtbPin, javax.swing.GroupLayout.PREFERRED_SIZE, 17, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(txtName, javax.swing.GroupLayout.DEFAULT_SIZE, 342, Short.MAX_VALUE)
                            .addComponent(jLabel1)
                            .addComponent(jLabel2)
                            .addComponent(jSeparator4, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 342, Short.MAX_VALUE)
                            .addComponent(jScrollPane2, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 342, Short.MAX_VALUE)))
                    .addGroup(jspRightLayout.createSequentialGroup()
                        .addComponent(btnNewAtt)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(btnRemAtt)))
                .addContainerGap())
        );
        jspRightLayout.setVerticalGroup(
            jspRightLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jspRightLayout.createSequentialGroup()
                .addComponent(jtbPin, javax.swing.GroupLayout.PREFERRED_SIZE, 18, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jLabel1)
                .addGap(4, 4, 4)
                .addComponent(txtName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jLabel2)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(txtValue, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 205, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jspRightLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(btnRemAtt)
                    .addComponent(btnNewAtt))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 85, Short.MAX_VALUE)
                .addComponent(jSeparator4, javax.swing.GroupLayout.PREFERRED_SIZE, 10, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jspRightLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(btnRevert)
                    .addComponent(btnSaveNode))
                .addContainerGap())
        );

        jspPane.setRightComponent(jspRight);

        jPanel1.setBorder(javax.swing.BorderFactory.createEtchedBorder());

        lblLastAction.setText("Ready");

        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(lblLastAction)
                .addContainerGap(536, Short.MAX_VALUE))
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(lblLastAction)
        );

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(hToolBar, javax.swing.GroupLayout.DEFAULT_SIZE, 591, Short.MAX_VALUE)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(jspPane, javax.swing.GroupLayout.DEFAULT_SIZE, 534, Short.MAX_VALUE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(vToolBar, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addContainerGap())))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addComponent(hToolBar, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(vToolBar, javax.swing.GroupLayout.DEFAULT_SIZE, 489, Short.MAX_VALUE)
                    .addComponent(jspPane, javax.swing.GroupLayout.DEFAULT_SIZE, 489, Short.MAX_VALUE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
        );

        java.awt.Dimension screenSize = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
        setBounds((screenSize.width-599)/2, (screenSize.height-575)/2, 599, 575);
    }// </editor-fold>//GEN-END:initComponents

    private void btnAboutActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnAboutActionPerformed
        new Help().setVisible(true);
    }//GEN-LAST:event_btnAboutActionPerformed

    private void btnOpenActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnOpenActionPerformed
        loading = true;
        JFileChooser fileChooser = new JFileChooser();
        fileChooser.setAcceptAllFileFilterUsed(false);
        fileChooser.addChoosableFileFilter(new XMLFileFilter());
        if (Persistence.getLastPath() != null) {
            fileChooser.setCurrentDirectory(new File(Persistence.getLastPath()));
        }
        int result = fileChooser.showOpenDialog(this);
        if (result == JFileChooser.APPROVE_OPTION) {
            try {
                Archive file = new Archive(fileChooser.getSelectedFile().getPath());
                Persistence.savePath(fileChooser.getSelectedFile().getParent());
                String content = file.readString();

                content = content.trim().replaceAll("\n", "");
                content = content.replaceAll("\t", "");
                content = content.replaceAll("(\\s){2,}", "");
                XmlParser parser = new XmlParser(content);
                Node nodo = parser.parseFromXML();
                this.jTree.removeAll();
                openFile = file;
                setTitle("XML JParser - " + fileChooser.getSelectedFile().getName());
                loadTreeNodes(nodo);
                jTree.setEnabled(true);
                btnSave.setEnabled(true);
                printLastAction("File " + fileChooser.getSelectedFile().getName() + "Opened");
            } catch (OnParsingException ex) {
                Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
            }
        }//End if
        loading = false;
    }//GEN-LAST:event_btnOpenActionPerformed

    private void btnSaveNodeActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnSaveNodeActionPerformed
        saveEdition();
}//GEN-LAST:event_btnSaveNodeActionPerformed

    private void btnRevertActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnRevertActionPerformed
        Node nodeObj = (Node) (((DefaultMutableTreeNode) onEditPath.getLastPathComponent()).getUserObject());
        loadEdit(nodeObj);
        checkContent();
    }//GEN-LAST:event_btnRevertActionPerformed

    private void btnEditActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnEditActionPerformed
        onEditPath = jTree.getSelectionPath();
        editNode();
    }//GEN-LAST:event_btnEditActionPerformed

    private void jTreeMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jTreeMouseClicked
        if (!jtbPin.isSelected()) {
            jspRight.setVisible(false);
        }
        //Si hay seleccionado un solo nodo, y no es el ra�z
        if (jTree.getSelectionCount() == 1
                && !((DefaultMutableTreeNode) jTree.getSelectionPath().getLastPathComponent()).isRoot()) {
            setButtonsAvailables(true);
            checkContent();
            if (evt.getButton() == evt.BUTTON3) {
                treePopupMenu.show(jTree, evt.getX(), evt.getY());
            }
        } else {//si hay mas de un nodo seleccionado o es el Ra�z
            setButtonsAvailables(false);
        }
        checkContent();
    }//GEN-LAST:event_jTreeMouseClicked

    private void pmnuEditActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_pmnuEditActionPerformed
        editNode();
    }//GEN-LAST:event_pmnuEditActionPerformed

    private void pmnuAddActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_pmnuAddActionPerformed
        String nNodeName = JOptionPane.showInputDialog(this, "New Node Name");
        if (nNodeName.compareToIgnoreCase("") == 0 || nNodeName == null) {
            return;
        }
        addChildToNode(nNodeName);
        saveEdition();
    }//GEN-LAST:event_pmnuAddActionPerformed

    private void btnNewActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnNewActionPerformed
        JFileChooser fileChooser = new JFileChooser();
        fileChooser.setAcceptAllFileFilterUsed(false);
        fileChooser.addChoosableFileFilter(new XMLFileFilter());
        if (Persistence.getLastPath() != null) {
            fileChooser.setCurrentDirectory(new File(Persistence.getLastPath()));
        }
        int result = fileChooser.showSaveDialog(this);
        if (result == JFileChooser.APPROVE_OPTION) {
            String nXMLName = fileChooser.getSelectedFile().getName();
            if (!nXMLName.endsWith(".xml")) {
                nXMLName += ".xml";
                openFile = new Archive(fileChooser.getSelectedFile().getPath() + ".xml");
            } else {
                openFile = new Archive(fileChooser.getSelectedFile().getPath());
            }
            setTitle("XML JParser - " + nXMLName);
            Node newXML = new Node(nXMLName, null);
            newXML.addNode(new Node("Root", null));
            loadTreeNodes(newXML);
            jTree.setEnabled(true);
            btnSave.setEnabled(true);
            printLastAction("New file " + nXMLName + " created.");
            setChanged(true);
            Persistence.savePath(fileChooser.getSelectedFile().getParent());
        }
    }//GEN-LAST:event_btnNewActionPerformed

    private void btnAddActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnAddActionPerformed
        String nNodeName = JOptionPane.showInputDialog(this, "New Node Name");
        if (nNodeName.compareToIgnoreCase("") == 0 || nNodeName == null) {
            return;
        }
        addChildToNode(nNodeName);
        saveEdition();
    }//GEN-LAST:event_btnAddActionPerformed

    private void btnRemoveActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnRemoveActionPerformed
        removeChildNode();
        checkContent();
        saveEdition();
    }//GEN-LAST:event_btnRemoveActionPerformed

    private void pmnuRemoveActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_pmnuRemoveActionPerformed
        removeChildNode();
        saveEdition();
    }//GEN-LAST:event_pmnuRemoveActionPerformed

    private void btnNewAttActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnNewAttActionPerformed
        ((DefaultTableModel) (jTable.getModel())).addRow(new String[2]);
}//GEN-LAST:event_btnNewAttActionPerformed

    private void btnRemAttActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnRemAttActionPerformed
        if (jTable.getSelectedRow() != -1) {
            ((DefaultTableModel) jTable.getModel()).removeRow(jTable.getSelectedRow());
        }
}//GEN-LAST:event_btnRemAttActionPerformed

    private void txtValueActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_txtValueActionPerformed
        // TODO add your handling code here:
    }//GEN-LAST:event_txtValueActionPerformed

    private void btnSaveActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnSaveActionPerformed
        try {
            openFile.writeString(new XmlParser(null).parseToXML(
                    (DefaultMutableTreeNode) jTree.getPathForRow(0).getLastPathComponent()),
                    false);
            printLastAction("Node " + this.getTitle().split(" - ")[1] + " Saved");
            JOptionPane.showMessageDialog(this,
                    this.getTitle().split(" - ")[1] + " succesfully saved.",
                    "File Save",
                    JOptionPane.INFORMATION_MESSAGE);
            setChanged(false);
        } catch (Exception e) {
            JOptionPane.showMessageDialog(this,
                    this.getTitle().split(" - ")[1] + " couldn't be saved.",
                    "File Save",
                    JOptionPane.WARNING_MESSAGE);
        }
    }//GEN-LAST:event_btnSaveActionPerformed

    private void jTreeValueChanged(javax.swing.event.TreeSelectionEvent evt) {//GEN-FIRST:event_jTreeValueChanged
        onEditPath = jTree.getSelectionPath();
        try {
            Node nodeObj = (Node) (((DefaultMutableTreeNode) onEditPath.getLastPathComponent()).getUserObject());
            loadEdit(nodeObj);
        } catch (NullPointerException e) {
            System.out.println("No node");
            return;
        }

        checkContent();
    }//GEN-LAST:event_jTreeValueChanged

    private void txtValueKeyReleased(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_txtValueKeyReleased
        checkContent();
    }//GEN-LAST:event_txtValueKeyReleased

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {

            public void run() {
                new Main().setVisible(true);
            }
        });
    }

    private void addChildToNode(String nNodeName) {
        DefaultMutableTreeNode nNode = new DefaultMutableTreeNode(new Node(nNodeName, null));
        MutableTreeNode node = (MutableTreeNode) jTree.getSelectionPath().getLastPathComponent();
        ((DefaultTreeModel) jTree.getModel()).insertNodeInto(nNode, node, node.getChildCount());
        printLastAction("Added new node '" + nNodeName + "'");
    }

    private void removeChildNode() {
        MutableTreeNode rNode = (MutableTreeNode) jTree.getSelectionPath().getLastPathComponent();
        ((DefaultTreeModel) jTree.getModel()).removeNodeFromParent(rNode);
        printLastAction("Node deleted");
    }

    private void setButtonsAvailables(Boolean enable) {
        pmnuAdd.setEnabled(enable);
        pmnuRemove.setEnabled(enable);
        pmnuEdit.setEnabled(enable);
        btnAdd.setEnabled(enable);
        btnRemove.setEnabled(enable);
        btnEdit.setEnabled(enable);
    }

    private void loadTreeNodes(Node node) {
        if (node.getName() == null
                || node.getName().compareTo(getTitle().split(" - ")[1]) == 0) {
            Roster<Node> nodes = node.getNodes();
            nodes.startIterator();
            Node.restartIDs();
            Node n = null;
            DefaultMutableTreeNode tNode = null;
            DefaultMutableTreeNode rootNode = new DefaultMutableTreeNode(
                    new Node(getTitle().split(" - ")[1], null));
            while (nodes.hasNext()) {
                n = nodes.next();
                tNode = new DefaultMutableTreeNode(n);
                loadNodesContent(tNode, n);
                rootNode.add(tNode);
            }
            jTree.setModel(new DefaultTreeModel(rootNode));
            setButtonsAvailables(false);
        }

    }

    private void loadNodesContent(DefaultMutableTreeNode treeNode, Node node) {
        if (node.getNodes().count() > 0) {

            Roster<Node> nodes = node.getNodes();
            nodes.startIterator();
            Node n;
            while (nodes.hasNext()) {
                n = nodes.next();
                DefaultMutableTreeNode child = new DefaultMutableTreeNode(n);
                loadNodesContent(child, n);
                treeNode.add(child);
            }
        }

    }
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton btnAbout;
    private javax.swing.JButton btnAdd;
    private javax.swing.JButton btnEdit;
    private javax.swing.JButton btnNew;
    private javax.swing.JButton btnNewAtt;
    private javax.swing.JButton btnOpen;
    private javax.swing.JButton btnRemAtt;
    private javax.swing.JButton btnRemove;
    private javax.swing.JButton btnRevert;
    private javax.swing.JButton btnSave;
    private javax.swing.JButton btnSaveNode;
    private javax.swing.JToolBar hToolBar;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JScrollPane jScrollPane2;
    private javax.swing.JToolBar.Separator jSeparator1;
    private javax.swing.JToolBar.Separator jSeparator2;
    private javax.swing.JPopupMenu.Separator jSeparator3;
    private javax.swing.JSeparator jSeparator4;
    private javax.swing.JTable jTable;
    private javax.swing.JTree jTree;
    private javax.swing.JSplitPane jspPane;
    private javax.swing.JPanel jspRight;
    private javax.swing.JToggleButton jtbPin;
    private javax.swing.JLabel lblLastAction;
    private javax.swing.JMenuItem pmnuAdd;
    private javax.swing.JMenuItem pmnuEdit;
    private javax.swing.JMenuItem pmnuRemove;
    private javax.swing.JPopupMenu treePopupMenu;
    private javax.swing.JTextField txtName;
    private javax.swing.JTextField txtValue;
    private javax.swing.JToolBar vToolBar;
    // End of variables declaration//GEN-END:variables

    private void loadEdit(Node node) {
        txtName.setText(node.getName());
        if (node.getValue() != null) {
            txtValue.setText(node.getValue());
        } else {
            txtValue.setText("");
        }
        String[] colNames = {"Attribute", "Value"};
        Object[][] props = new Object[node.getProperties().size()][2];
        if (node.getProperties() != null) {
            for (int i = 0; i < node.getProperties().size(); i++) {
                props[i][0] = node.getProperties().keySet().toArray()[i];
                props[i][1] = node.getProperties().values().toArray()[i];
            }
        }
        jTable.setModel(new DefaultTableModel(props, colNames));
        printLastAction("Node " + node.getName() + " Loaded");
    }

    private void checkContent() {
        DefaultMutableTreeNode dmtn = null;
        try {
            dmtn = ((DefaultMutableTreeNode) onEditPath.getLastPathComponent());
        } catch (Exception e) {
            return;
        }
        if (loading || dmtn.isRoot()) {
            return;
        }
        if (txtValue.getText().trim().compareToIgnoreCase("") != 0) {
            pmnuAdd.setEnabled(false);
            btnAdd.setEnabled(false);
            txtValue.setEnabled(true);
        } else {
            if (dmtn.getChildCount() == 0) {
                pmnuAdd.setEnabled(true);
                btnAdd.setEnabled(true);
                txtValue.setEnabled(true);
            } else {
                pmnuAdd.setEnabled(true);
                btnAdd.setEnabled(true);
                txtValue.setEnabled(false);
            }
        }


    }

    private void saveEdition() {
        Node toSave = null;
        try {
            toSave = ((Node) ((DefaultMutableTreeNode) (onEditPath.getLastPathComponent())).getUserObject());
        } catch (NullPointerException e) {
            return;
        }
        toSave.setName(txtName.getText());
        toSave.setValue(txtValue.getText());
        if (txtValue.getText().compareToIgnoreCase("") == 0) {
            toSave.setValue(null);
        }
        TableModel model = jTable.getModel();
        toSave.getProperties().clear();
        for (int i = 0; i < model.getRowCount(); i++) {
            if (model.getValueAt(i, 0) != null && model.getValueAt(i, 1) != null) {
                toSave.addPropertie(model.getValueAt(i, 0).toString(), model.getValueAt(i, 1).toString());
            }
        }
        printLastAction("Node " + toSave.getName() + " Saved");
        if (!jtbPin.isSelected()) {
            jspPane.setDividerLocation(1.0);
        }
        checkContent();
        setChanged(true);
    }

    private void printLastAction(String action) {
        lblLastAction.setText("Last Action: " + action);
    }

    private void setChanged(boolean b) {
        changed = b;
        if (b) {
            btnSave.setIcon(new javax.swing.ImageIcon(getClass().getResource("/images/disk_unsave.png")));
        } else {
            btnSave.setIcon(new javax.swing.ImageIcon(getClass().getResource("/images/disk_multiple.png")));
        }
    }
}
